package com.java.order.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.java.clients.ProductClient;
import com.java.order.mapper.OrderMapper;
import com.java.order.service.OrderService;
import com.java.param.*;
import com.java.pojo.Cart;
import com.java.pojo.Order;
import com.java.pojo.Product;
import com.java.to.OrderToProduct;
import com.java.utils.R;
import com.java.vo.AdminOrderVo;
import com.java.vo.CartVo;
import com.java.vo.OrderVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.SortParameters;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService{
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private ProductClient productClient;
    @Autowired
    private OrderMapper orderMapper;
    /**
     * 保存订单数据
     * 1.将购物车数据转成订单数据
     * 2.订单数据批量保存
     * 3.商品库存修改消息,productId,num
     * 4.发送购物车修改消息
     * @param orderParam
     * @return
     */
    @Transactional
    @Override
    public R save(OrderParam orderParam) {
        //1.直接调用service的方法 2.baseMapper内置对象，调用mapper原有的方法

        //准备数据
        List<Integer> cartIds = new ArrayList<>();
        List<OrderToProduct> orderToProducts = new ArrayList<>();
        List<Order> orderList = new ArrayList<>();

        //填充数据
        Integer userId = orderParam.getUserId();
        long orderId = System.currentTimeMillis();

        List<CartVo> products = orderParam.getProducts();
        for (CartVo cartVo : products) {
            cartIds.add(cartVo.getId());
            OrderToProduct orderToProduct = new OrderToProduct();
            orderToProduct.setProductId(cartVo.getProductID());
            orderToProduct.setNum(cartVo.getNum());
            orderToProducts.add(orderToProduct);

            Order order = new Order();
            order.setOrderId(orderId);
            order.setOrderTime(orderId);
            order.setProductId(cartVo.getProductID());
            order.setUserId(userId);
            order.setProductNum(cartVo.getNum());
            order.setProductPrice(cartVo.getPrice());
            orderList.add(order);

        }
        //批量保存
        saveBatch(orderList);

        //发送购物车消息
        rabbitTemplate.convertAndSend("topic.ex","clear.cart",cartIds);
        //发送商品消息
        rabbitTemplate.convertAndSend("topic.ex","sub.number",orderToProducts);


        return R.ok("购买成功！");
    }

    /**
     * 分组查询顶单数据
     * 1.查询用户对应的全部订单项
     * 2.利用stream进行订单分组，orderId
     * 3.查询订单的全部商品集合，并stream组成map
     * 4.封装返回的OrderVo对象
     * @param cartListParam
     * @return
     */
    @Override
    public R list(CartListParam cartListParam) {
        //查询用户对应的全部订单项
        QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id",cartListParam.getUserId());
        List<Order> orders = list(queryWrapper);
        //利用stream进行订单分组，orderId
        Map<Long, List<Order>> orderMap = orders.stream().collect(Collectors.groupingBy(Order::getOrderId));
        //查询订单的全部商品集合
        List<Integer> productIds = orders.stream().map(Order::getProductId).collect(Collectors.toList());
        ProductCollectParam productCollectParam = new ProductCollectParam();
        productCollectParam.setProductIds(productIds);
        List<Product> products = productClient.cartList(productCollectParam);
        //并stream组成map
        Map<Integer, Product> productMap = products.stream().collect(Collectors.toMap(Product::getProductId, v -> v));
        //结果封装
        List<List<OrderVo>> result = new ArrayList<>();
        //遍历订单项集合（每个订单项中可能含有多个顶单）
        for (List<Order> orderList : orderMap.values()) {
            List<OrderVo> orderVoList = new ArrayList<>();
            //遍历每一个订单
            for (Order order : orderList) {
                OrderVo orderVo = new OrderVo();
                orderVo.setProductName(productMap.get(order.getProductId()).getProductName());
                orderVo.setProductPicture(productMap.get(order.getProductId()).getProductPicture());
                BeanUtils.copyProperties(order,orderVo);
                orderVoList.add(orderVo);
            }
            result.add(orderVoList);
        }
        R ok = R.ok("订单数据查询成功！", result);
        log.info("OrderServiceImpl.list 业务已经完成,结果:{}", ok);
        return ok;
    }

    /**
     * 根据商品id检查所有用户购物车是否有该商品
     *
     * @param productIdRemoveParam
     * @return
     */
    @Override
    public R check(ProductIdRemoveParam productIdRemoveParam) {
        QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("product_id",productIdRemoveParam.getProductId());
        Order order = orderMapper.selectOne(queryWrapper);
        if(order!=null){
            return R.fail("存在用户订单含有该商品，不可删除！");
        }
        return R.ok("不存在用户订单含有该商品，可以删除！");
    }

    /**
     * 分页分组查询订单详情
     *
     * @param pageParam
     * @return
     */
    @Override
    public R adminList(PageParam pageParam) {
        Integer offset = (pageParam.getCurrentPage()-1)*pageParam.getPageSize();
        Integer pageSize = pageParam.getPageSize();

        List<AdminOrderVo> adminOrderVo = orderMapper.selectAdminOrders(offset,pageSize);

        return R.ok("订单数据查询成功！",adminOrderVo);
    }
}
